package cz.maestro.sokodroid;

import java.util.*;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.*;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android.content.*;
import android.content.pm.ActivityInfo;
import android.hardware.SensorManager;

public class Sokodroid extends Activity implements OnItemClickListener {
	private Vibrator vibrator;

	private GLView gameView;
	private ListView levelView;
	private LevelManager levelManager;

	enum CurrentView {
		MENU, GAME
	};

	private CurrentView currentView = CurrentView.MENU;

	private Maze maze;
	private int currentLevelIndex;
	private int currentLevelMoves;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
		levelManager = new LevelManager(this);

		initMenuView();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.menu, menu);
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	        case R.id.exit:     
	        	finish();
	        	break;
	        case R.id.about:
	        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	        	builder.setTitle("About Sokodroid");
	        	
				builder.setMessage("Sokodroid for Android\nVersion 1.0.1\n\nhttp://code.google.com/p/sokodroid\n\n This is an opensource game created as school project.\nCreated by Martin Spinler")
						.setPositiveButton("OK",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int which) {
										return;
									}
								});
				AlertDialog alert = builder.create();
				alert.show();
	        	
	        	break;
	    }
	    return true;
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		outState.putInt("State", currentView == CurrentView.GAME ? 1 : 0);
		outState.putInt("Level", currentLevelIndex);
		super.onSaveInstanceState(outState);
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		if (savedInstanceState.getInt("State") == 1)
			initGameView(levelManager.getLevel(savedInstanceState
					.getInt("Level")));
		else
			initMenuView();
	}

	public void initMenuView() {
		currentView = CurrentView.MENU;
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
		setContentView(R.layout.main);

		/*Button exit = (Button) findViewById(R.id.ButtonExit);
		exit.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				finish();
			}
		});
*/
		levelView = (ListView) findViewById(R.id.LevelList);
		levelView.setAdapter(levelManager);
		levelView.setOnItemClickListener(this);
		levelView.setClickable(true);
		levelView.requestFocus();
	}

	public void initGameView(Level level) {
		currentView = CurrentView.GAME;
		gameView = new GLView(this);
		((SensorManager) getSystemService(Context.SENSOR_SERVICE))
				.registerListener(gameView, SensorManager.SENSOR_ORIENTATION,
						SensorManager.SENSOR_DELAY_GAME);
		setContentView(gameView);

		SharedPreferences p = getPreferences(Activity.MODE_PRIVATE);
		String m = p.getString("level" + level.index + "_moveSequence", "");

		maze = new Maze(this, level.index);
		gameView.renderer.maze = maze;
		currentLevelIndex = level.index;
		currentLevelMoves = m.length();

		for (int i = 0; i < m.length(); i++) {
			switch (m.charAt(i)) {
			case 'U':
				maze.move(Direction.UP, true);
				break;
			case 'D':
				maze.move(Direction.DOWN, true);
				break;
			case 'L':
				maze.move(Direction.LEFT, true);
				break;
			case 'R':
				maze.move(Direction.RIGHT, true);
				break;
			}
		}

		final int x = maze.droid.x, y = maze.droid.y;
		gameView.queueEvent(new Runnable() {
			public void run() {
				gameView.renderer.setCamera(x, y, true);
			}
		});

	}

	public void destroyGameView() {
		((SensorManager) getSystemService(Context.SENSOR_SERVICE))
				.unregisterListener(gameView);
	}

	public void move(Direction dir) {
		SharedPreferences p = getPreferences(Activity.MODE_PRIVATE);
		SharedPreferences.Editor ed = p.edit();

		int ret = maze.move(dir);
		if (ret > 0) {
			char d = ' ';
			switch (dir) {
			case UP:
				d = 'U';
				break;
			case DOWN:
				d = 'D';
				break;
			case LEFT:
				d = 'L';
				break;
			case RIGHT:
				d = 'R';
				break;
			}
			String m = p.getString("level" + currentLevelIndex
					+ "_moveSequence", "");
			m += String.format("%c", d);
			ed.putString("level" + currentLevelIndex + "_moveSequence", m);
			ed.commit();

			currentLevelMoves++;

			final int x = maze.droid.x, y = maze.droid.y;
			gameView.queueEvent(new Runnable() {
				public void run() {
					gameView.renderer.setCamera(x, y, false);
				}
			});
		} else if (ret == -1) {
			vibrator.vibrate(120);
		}
		if (ret == 3) {
			try {
				Thread.sleep(700);
			} catch (Exception e) {
			}

			destroyGameView();
			ed.putInt("level" + currentLevelIndex + "_completed", 1);
			if (p.getInt("level" + currentLevelIndex + "_moves",
					Integer.MAX_VALUE) > currentLevelMoves)
				ed.putInt("level" + currentLevelIndex + "_moves",
						currentLevelMoves);
			ed.putString("level" + currentLevelIndex + "_moveSequence", "");
			ed.commit();

			levelManager.reload();

			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage("Congratulation!\nYou won this level.")
					.setPositiveButton("OK",
							new DialogInterface.OnClickListener() {
								public void onClick(DialogInterface dialog,
										int which) {
									return;
								}
							});
			AlertDialog alert = builder.create();
			alert.show();

			initMenuView();
		}
	}

	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

		initGameView(levelManager.getLevel(arg2));
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
	}

	public boolean onKeyDown(int key, KeyEvent event) {
		if (currentView == CurrentView.GAME) {
			Direction dir = null;
			switch (key) {
			case KeyEvent.KEYCODE_MENU:
				destroyGameView();
				initMenuView();
				return true;
			case KeyEvent.KEYCODE_BACK:
				maze = new Maze(this, currentLevelIndex);
				gameView.renderer.maze = maze;

				currentLevelMoves = 0;
				getPreferences(Activity.MODE_PRIVATE).edit().putString(
						"level" + currentLevelIndex + "_moveSequence", "")
						.commit();
				return true;

			case KeyEvent.KEYCODE_W:
			case KeyEvent.KEYCODE_DPAD_UP:
				dir = Direction.UP;
				break;
			case KeyEvent.KEYCODE_S:
			case KeyEvent.KEYCODE_DPAD_DOWN:
				dir = Direction.DOWN;
				break;
			case KeyEvent.KEYCODE_A:
			case KeyEvent.KEYCODE_DPAD_LEFT:
				dir = Direction.LEFT;
				break;
			case KeyEvent.KEYCODE_D:
			case KeyEvent.KEYCODE_DPAD_RIGHT:
				dir = Direction.RIGHT;
				break;
			}
			if (dir != null) {
				move(dir);
				return true;
			}
		} else if (currentView == CurrentView.MENU
				&& key == KeyEvent.KEYCODE_BACK) {
			finish();
			return true;
		}
		return false;
	}
}

class Level {
	public int index;
	public int moves;
	public String name;
	public boolean completed;
}

class LevelManager extends BaseAdapter {

	private List<Level> mLevels;
	Context mContext;

	LevelManager(Context context) {
		mContext = context;
		mLevels = new LinkedList<Level>();
		reload();
	}

	public void reload() {
		SharedPreferences p = ((Activity) mContext)
				.getPreferences(Activity.MODE_PRIVATE);
		Level s;
		mLevels.clear();
		for (int i = 0; i < Mazes.count; i++) {
			s = new Level();
			s.name = Mazes.name[i];
			s.index = i;
			s.completed = p.getInt("level" + i + "_completed", 0) > 0 ? true
					: false;
			s.moves = p.getInt("level" + i + "_moves", 0);
			mLevels.add(s);
		}
	}

	public int getCount() {
		return mLevels.size();
	}

	public Object getItem(int position) {
		return position;
	}

	public Level getLevel(int position) {
		return mLevels.get(position);
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		int icon;
		String text = "";
		Level l = mLevels.get(position);

		if (l.completed) {
			icon = R.drawable.levelc;
			text += String.format("   Completed    (%d moves)", l.moves);
		} else {
			icon = R.drawable.level;
			text += "   Not completed\n";
		}
		
		TextView t1 = new TextView(mContext);
		TextView t2 = new TextView(mContext);
		ImageView i = new ImageView(mContext);
		LinearLayout l1 = new LinearLayout(mContext);
		LinearLayout l2 = new LinearLayout(mContext);

		l1.addView(i);
		l1.addView(l2);
		l2.addView(t1);
		l2.addView(t2);
		l2.setOrientation(LinearLayout.VERTICAL);
		
		t1.setTextSize(20.0f);
		t1.setText(l.name);
		t2.setText(text);
		i.setImageResource(icon);
		return l1;
	}
}